<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Address_Decoder_Static.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="A flexible address decoder. Works for any address range at any starting point. The base and bound addresses are set as parameters, so the range is fixed. This decoder works by checking if the input address lies between the base and bound (inclusive) of a range by comparing against each possible address within the range, then outputs the OR-reduction of all these checks.">
<title>Address Decoder Static</title>
</head>
<body>

<p class="inline bordered"><b><a href="./Address_Decoder_Static.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>

<h1>Address Decoder (Static)</h1>
<p>A flexible address decoder. Works for any address range at any starting
 point. The base and bound addresses are set as parameters, so the range is
 fixed. This decoder works by checking if the input address lies between the
 base and bound (inclusive) of a range by comparing against each possible
 address within the range, then outputs the OR-reduction of all these
 checks.</p>
<p>But there are a couple of caveats: your CAD tool will have to create
 a little netlist for up to all 2^ADDR_WIDTH possible addresses, and store
 the matches into a vector of up to 2^ADDR_WIDTH bits long, depending on the
 base and bound addresses.  Elaborating and optimizing this logic can take
 a <em>very</em> long time and, as I understand it, Verilog implementations have
 a maximum vector width of a million or so, so this decoder will be likley
 unusable for address ranges more than 20 bits wide.</p>
<p>Also, even if your CAD tool can handle wider vectors, because we use an
 integer as counter, this decoder cannot be guaranteed to work for address
 ranges exceeding 32 bits, depending on your Verilog implementation.</p>
<p><strong>I do not recommend this implementation.</strong> I include it because I have put
 it to good use inside a CPU for decoding register operands, and it might be
 a good choice for very small, fixed address ranges if your CAD tool cannot
 fully optimize the <a href="./Address_Decoder_Behavioural.html">Behavioural Address
 Decoder</a>.</p>

<pre>
`default_nettype none

module <a href="./Address_Decoder_Static.html">Address_Decoder_Static</a>
#(
    parameter       ADDR_WIDTH          = 0,
    parameter       ADDR_BASE           = 0,
    parameter       ADDR_BOUND          = 0
)
(
    input   wire    [ADDR_WIDTH-1:0]    addr,
    output  reg                         hit
);

    localparam ADDR_COUNT = ADDR_BOUND - ADDR_BASE + 1;
    localparam COUNT_ZERO = {ADDR_COUNT{1'b0}};

    initial begin
        hit = 1'b0;
    end

    integer                     i;
    reg     [ADDR_COUNT-1:0]    per_addr_match = COUNT_ZERO;
</pre>

<p>Check each address in base/bound range for match, and store it in a vector
 for later OR-reduction.  Note that we select only the bit range we need
 from the index <code>i</code> so it doesn't raise a width mismatch warning when
 compared to the input address.  This does mean problems if <code>ADDR_WIDTH</code> is
 greater than 32 bits.</p>

<pre>
    always @(*) begin
        for(i = ADDR_BASE; i <= ADDR_BOUND; i = i + 1) begin : addr_decode
            per_addr_match[i-ADDR_BASE] = (addr == i[ADDR_WIDTH-1:0]);
        end
    end

    always @(*) begin : is_hit
        hit = |per_addr_match;
    end 

endmodule
</pre>

<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>

